package com.octopus.optiworks.controller;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import com.octopus.optiworks.model.*;
import com.octopus.optiworks.service.StepService;
import com.octopus.optiworks.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/spec")
public class StepSpecController {

	private StepSpecValidator stepSpecValidator = new StepSpecValidator();

	@Autowired
    private UserService userService;
	
	@Autowired
    private StepService stepService;

    @RequestMapping("/manage.o")
    @RequiresPermissions("spec:manage")
    public void manage(Model model) {
    	Employee user =  this.userService.getCurrentUser();
    	model.addAttribute("currentUser", user);
        model.addAttribute("stepSpecs", stepService.getAllStepSpecs());
    }

    @RequestMapping(value="/edit.o",method= RequestMethod.GET)
    @RequiresPermissions("spec:edit")
    public String showEditStepSpecForm(HttpServletRequest request, Model model, @RequestParam Long stepSpecId, @ModelAttribute StepSpec stepSpec) {
    	Employee cu =  this.userService.getCurrentUser();
    	model.addAttribute("currentUser", cu);
    	model.addAttribute("action", "Edit");
    	if(stepSpec.getId() == null){
	        StepSpec spec = stepService.getStepSpec(stepSpecId);
	        stepSpec.setId(stepSpecId);
	        stepSpec.setName(spec.getName());
	        stepSpec.setDescription(spec.getDescription());
	        stepSpec.setStep10_1DataId(spec.getStep10_1DataId());
	        stepSpec.setStep10_1OperationId(spec.getStep10_1OperationId());
	        stepSpec.setStep10_1Data(spec.getStep10_1Data());
	        stepSpec.setStep10_1Operation(spec.getStep10_1Operation());
	        
	        stepSpec.setStep10_2DataId(spec.getStep10_2DataId());
	        stepSpec.setStep10_2OperationId(spec.getStep10_2OperationId());
	        stepSpec.setStep10_2Data(spec.getStep10_2Data());
	        stepSpec.setStep10_2Operation(spec.getStep10_2Operation());
	        
	        stepSpec.setStep30_2DataId(spec.getStep30_2DataId());
	        stepSpec.setStep30_2OperationId(spec.getStep30_2OperationId());
	        stepSpec.setStep30_2Data(spec.getStep30_2Data());
	        stepSpec.setStep30_2Operation(spec.getStep30_2Operation());
	        
	        stepSpec.setStep80DataId(spec.getStep80DataId());
	        stepSpec.setStep80OperationId(spec.getStep80OperationId());
	        stepSpec.setStep80Data(spec.getStep80Data());
	        stepSpec.setStep80Operation(spec.getStep80Operation());
	        
	        stepSpec.setStep140_1DataId(spec.getStep140_1DataId());
	        stepSpec.setStep140_1OperationId(spec.getStep140_1OperationId());
	        stepSpec.setStep140_1Data(spec.getStep140_1Data());
	        stepSpec.setStep140_1Operation(spec.getStep140_1Operation());
	        
	        stepSpec.setStep140_2DataId(spec.getStep140_2DataId());
	        stepSpec.setStep140_2OperationId(spec.getStep140_2OperationId());
	        stepSpec.setStep140_2Data(spec.getStep140_2Data());
	        stepSpec.setStep140_2Operation(spec.getStep140_2Operation());
	        
	        stepSpec.setStep160DataId(spec.getStep160DataId());
	        stepSpec.setStep160OperationId(spec.getStep160OperationId());
	        stepSpec.setStep160Data(spec.getStep160Data());
	        stepSpec.setStep160Operation(spec.getStep160Operation());
	        
	        stepSpec.setStep170_1DataId(spec.getStep170_1DataId());
	        stepSpec.setStep170_1OperationId(spec.getStep170_1OperationId());
	        stepSpec.setStep170_1Data(spec.getStep170_1Data());
	        stepSpec.setStep170_1Operation(spec.getStep170_1Operation());
	        
	        stepSpec.setStep170_2DataId(spec.getStep170_2DataId());
	        stepSpec.setStep170_2OperationId(spec.getStep170_2OperationId());
	        stepSpec.setStep170_2Data(spec.getStep170_2Data());
	        stepSpec.setStep170_2Operation(spec.getStep170_2Operation());
    	}
    	model.addAttribute("numOps", this.getNumOpsList());
    	model.addAttribute("strOps", this.getStrOpsList());
        return "spec/edit";
    }

    @RequestMapping(value="/edit.o",method= RequestMethod.POST)
    @RequiresPermissions("spec:edit")
    public String editStepSpec(HttpServletRequest request, Model model, @RequestParam Long stepSpecId, @ModelAttribute StepSpec stepSpec, BindingResult errors) {
    	stepSpecValidator.validate(stepSpec, errors );
        if( errors.hasErrors() ) {
        	model.addAttribute("action", "Edit");
        	model.addAttribute("numOps", this.getNumOpsList());
        	model.addAttribute("strOps", this.getStrOpsList());
            return "spec/edit";
        }
        stepSpec.setId(stepSpecId);
        try{
        	stepService.updateStepSpec(stepSpec);
        }catch (org.springframework.jdbc.UncategorizedSQLException e){
        	e.printStackTrace();
        	errors.rejectValue( "name", "error.name.exist", "The name has already existed." );
        	model.addAttribute("action", "Edit");
        	model.addAttribute("numOps", this.getNumOpsList());
        	model.addAttribute("strOps", this.getStrOpsList());
            return "spec/edit";
        }
        return "redirect:/spec/manage.o";
    }

    @RequestMapping("/delete.o")
    @RequiresPermissions("spec:delete")
    public String deleteStepSpec(@RequestParam Long stepSpecId) {
        stepService.deleteStepSpec( stepSpecId );
        return "redirect:/spec/manage.o";
    }
    
    @RequestMapping(value="/create.o",method= RequestMethod.GET)
    public String showCreateStepSpecForm(HttpServletRequest request, Model model, @ModelAttribute StepSpec stepSpec) {
    	Employee cu =  this.userService.getCurrentUser();
    	model.addAttribute("currentUser", cu);
    	model.addAttribute("numOps", this.getNumOpsList());
    	model.addAttribute("strOps", this.getStrOpsList());
    	model.addAttribute("action", "Create");
    	
    	stepSpec.setStep10_1Data(new Step10_1Data());
    	stepSpec.setStep10_1Operation(new Step10_1Data());
    	stepSpec.setStep10_2Data(new Step10_2Data());
    	stepSpec.setStep10_2Operation(new Step10_2Data());
    	stepSpec.setStep30_2Data(new Step30_2Data());
    	stepSpec.setStep30_2Operation(new Step30_2Data());
    	stepSpec.setStep80Data(new Step80Data());
    	stepSpec.setStep80Operation(new Step80Data());
    	stepSpec.setStep140_1Data(new Step140_1Data());
    	stepSpec.setStep140_1Operation(new Step140_1Data());
    	stepSpec.setStep140_2Data(new Step140_2Data());
    	stepSpec.setStep140_2Operation(new Step140_2Data());
    	stepSpec.setStep160Data(new Step160Data());
    	stepSpec.setStep160Operation(new Step160Data());
    	stepSpec.setStep170_1Data(new Step170_1Data());
    	stepSpec.setStep170_1Operation(new Step170_1Data());
    	stepSpec.setStep170_2Data(new Step170_2Data());
    	stepSpec.setStep170_2Operation(new Step170_2Data());
        return "spec/edit";
    }

    @RequestMapping(value="/create.o",method= RequestMethod.POST)
    public String createStepSpec(HttpServletRequest request, Model model, @ModelAttribute StepSpec stepSpec, BindingResult errors) {
    	stepSpecValidator.validate(stepSpec, errors );
        if( errors.hasErrors() ) {
        	model.addAttribute("action", "Create");
        	model.addAttribute("numOps", this.getNumOpsList());
        	model.addAttribute("strOps", this.getStrOpsList());
            return "spec/edit";
        }
        try{
        	stepService.createStepSpec(stepSpec);
        }catch (org.springframework.dao.DataIntegrityViolationException e){
        	e.printStackTrace();
        	errors.rejectValue( "name", "error.name.exist", "The name has already existed." );
        	model.addAttribute("action", "Create");
        	model.addAttribute("numOps", this.getNumOpsList());
        	model.addAttribute("strOps", this.getStrOpsList());
            return "spec/edit";
        }
        return "redirect:/spec/manage.o";
    }
    
    private List<String> getNumOpsList(){
    	List<String> numOps = new ArrayList<String>();
    	numOps.add(StepSpec.OPERATION_NUM_NA);
    	numOps.add(StepSpec.OPERATION_NUM_EQ);
    	numOps.add(StepSpec.OPERATION_NUM_NOEQ);
    	numOps.add(StepSpec.OPERATION_NUM_LT);
    	numOps.add(StepSpec.OPERATION_NUM_NOMT);
    	numOps.add(StepSpec.OPERATION_NUM_MT);
    	numOps.add(StepSpec.OPERATION_NUM_NOLT);
    	return numOps;
    }
    
    private List<String> getStrOpsList(){
    	List<String> strOps = new ArrayList<String>();
    	strOps.add(StepSpec.OPERATION_STR_NA);
    	strOps.add(StepSpec.OPERATION_STR_EQ);
    	strOps.add(StepSpec.OPERATION_STR_NOEQ);
    	return strOps;
    }

}
